//============================================================================
// Nome        : Empresa.cpp
// Autores     : T1G7
//                                      Felipe Galvão do Espírito Santo
//                                      Ivanilda Maísa Costa Brazão de Almeida
//                                      Paulo Jorge de Faria dos Reis
// Versão      : 1.0
// Data        : Maio de 2011
// Copyright   : Creative Commons 2.0
// Descrição   : CAL 2011 - TG1
//               Tema 12 - Transporte de pacientes de uma clínica de saúde.
//============================================================================

#include "Empresa.h"

#define SEPARADOR "|"

unsigned int Empresa::instancias = 0;

//! No construtor de Empresa é fornecido o ficheiro de arquivo utilizado ou a utilizar para guardar os dados.
Empresa::Empresa(string ficheiro, int permissoes) {
	//TODO abrir ficheiro arquivo
	int sucesso;
	arquivo = ficheiro; 					//! Nome do ficheiro utilizado para os dados do campeonato.
	sucesso = iData.carregarDados(arquivo, SEPARADOR);	//! Processa o conteúdo do ficheiro e recria os objectos.
	iTex.ligarDados(iData);	 				//! Passar uma referência dos dados para a Interface
	instancia = ++(Empresa::instancias);
}

Empresa::~Empresa() {

}

void Empresa::terminar()
{
exit(1);
}


// Menu principal
int Empresa::iniciar() {

	string escolha;

	//! Preparação do Menu Principal
	vector<string> aMostrar;
	aMostrar.push_back("Tema 12");
	aMostrar.push_back("separador");
	aMostrar.push_back("1 - Gestão de Clientes.");
	aMostrar.push_back("2 - Gestão de Veiculos.");
	aMostrar.push_back("3 - Gestão de Sucursais.");
	aMostrar.push_back("4 - Gestão de Consultas.");
	aMostrar.push_back("5 - Gestão de Rotas.");
	aMostrar.push_back("9 - Ajuda.");
	aMostrar.push_back("0 - Sair.");
	iTex.menuNaConsola(aMostrar);
	escolha = iTex.smsRetorno("Escolha a opção pretendida:");


	if (escolha == "0")
	{
		terminar(); 		//! Gravar os dados da aplicação.
		return 0;
	}
	else if (escolha == "1")
		gestaoClientes(); 		//! Gestão dos clientes
	else if (escolha == "2")
		gestaoVeiculos(); 		//! Gestão dos veículos
	else if (escolha == "3")
		gestaoSucursal(); 		//! Gestão das sucursais
	else if (escolha == "4")
		gestaoConsultas(); 		//! Gestão de consultas
	else if (escolha == "5")
		gestaoRotas(); 			//! Gestão de consultas
	else if (escolha == "9")
		iTex.ajuda("menuPrincipal"); //! Menu de ajuda, existe em todos os menus.
	else
		iniciar();

	return 0; //! Retorna ao main da aplicação.
}

// Gestão de Clientes
void Empresa::gestaoClientes()
{
	string escolha;

	//Preparação do Menu Gestão de  Clientes.
	vector<string> aMostrar;
	aMostrar.push_back("Gestão de Clientes");
	aMostrar.push_back("separador");
	aMostrar.push_back("1 - Registar Clientes.");
	aMostrar.push_back("2 - Alterar Clientes.");
	aMostrar.push_back("3 - Desativar Clientes.");
	aMostrar.push_back("4 - Consultar Clientes.");
	aMostrar.push_back("9 - Ajuda.");
	aMostrar.push_back("0 - Sair.");
	iTex.menuNaConsola(aMostrar);
	escolha = iTex.smsRetorno("Escolha a opção pretendida:");


	if (escolha == "0")
		{
			iniciar(); 						//! Retorna ao menu anterior( nesse caso ao Menu Principal).
		}
		else if (escolha == "1")
			registarCliente(); 				//! Opção para registar um cliente.
		else if (escolha == "2")
			alterarCliente(); 				//! Opção para alterar um cliente.
		else if (escolha == "3")
			desativarCliente(); 			//! Opção para desativar um cliente.
		else if (escolha == "4")
			consultarCliente(); 			//! apresenta os dados do cliente.
		else if (escolha == "9")
			iTex.ajuda("menuPrincipal"); 	//! Menu de ajuda, existe em todos os menus.
		else

			gestaoClientes();

}

// Gestão de Veiculos
void Empresa::gestaoVeiculos()
{
	    string escolha;

		//Preparação do Menu Gestão de  Veículos.
		vector<string> aMostrar;
		aMostrar.push_back("Gestão de Veículos");
		aMostrar.push_back("separador");
		aMostrar.push_back("1 - Capacidade do Veiculo.");
		aMostrar.push_back("2 - Clientes Alocados.");
		//aMostrar.push_back("3 - Sucursal Associado.");
		iTex.menuNaConsola(aMostrar);
		escolha = iTex.smsRetorno("Escolha a opção pretendida:");


		if (escolha == "0")
			{
				iniciar(); 							//! Retorna ao menu anterior( nesse caso ao Menu Principal).
			}
			else if (escolha == "1")
				capacidadeVeiculo(); 				//! Quantidade de passageiros que o veiculo suporta
			else if (escolha == "2")
			     clientesAlocados(); 				//! Quantidade de Clientes alocados no veiculo.
			//else if (escolha == 3)

				// sucursalAssociado(); 			//!  A sucursal a que o veiculo pertence.
			else if (escolha == "9")
					iTex.ajuda("menuPrincipal");	 //! Menu de ajuda, existe em todos os menus.
			else
				gestaoVeiculos();


}

// Gestão de sucursais
void Empresa::gestaoSucursal()
{
		string escolha;

		//Preparação do Menu Gestão de  Sucursais.
		vector<string> aMostrar;
		aMostrar.push_back("Gestão de Sucursais");
		aMostrar.push_back("separador");
		aMostrar.push_back("1 - Clientes da Sucursal.");
		aMostrar.push_back("2 - Veiculo da Sucursal.");
		aMostrar.push_back("3 - Desativar Sucursal.");
		aMostrar.push_back("9 - Ajuda.");
		aMostrar.push_back("0 - Sair.");
		iTex.menuNaConsola(aMostrar);
		escolha = iTex.smsRetorno("Escolha a opção pretendida:");

		if (escolha == "0")
			{
				iniciar(); 					//! Retorna ao menu anterior( nesse caso ao Menu Principal).
			}
			else if (escolha == "1")
				listaClientes(); 			//! mostra a lista dos clientes da sucursal
			else if (escolha == "2")
				veiculoAssociado(); 		//! mostra o veiculo associado
			else if (escolha == "3")
				desativarSucursal(); 		//! apaga a sucursal
			else if (escolha == "9")
				iTex.ajuda("menuPrincipal"); 	//! Menu de ajuda, existe em todos os menus.
			else
				gestaoSucursal();
}

// Gestão de Consultas
void Empresa::gestaoConsultas()
{
	string escolha;

	//Preparação do Menu Gestão de  Clientes.
	vector<string> aMostrar;
	aMostrar.push_back("Consultas");
	aMostrar.push_back("separador");
	aMostrar.push_back("1 - Escolher Cliente.");
	aMostrar.push_back("9 - Ajuda.");
	aMostrar.push_back("0 - Sair.");
	iTex.menuNaConsola(aMostrar);
	escolha = iTex.smsRetorno("Escolha a opção pretendida:");


	if (escolha == "0")
		{
			iniciar(); 						//! Retorna ao menu anterior( nesse caso ao Menu Principal).
		}
		else if (escolha == "1")
			dadosCliente(); 				//! Opção para registar um cliente.
		else if (escolha == "9")
			iTex.ajuda("menuPrincipal"); 	//! Menu de ajuda, existe em todos os menus.
		else

			gestaoConsultas();
}

// Gestão de Rotas
void Empresa::gestaoRotas()
{
	string escolha;
	vector<string> aMostrar;
	aMostrar.clear();
	aMostrar.push_back("Gestão de Rotas");
	aMostrar.push_back("separador");
	aMostrar.push_back("1 - Algoritmo 1 - Uma única rota de 1 veiculo.");
	aMostrar.push_back("2 - Rota Algoritmo2");
	aMostrar.push_back("3 - Rota Algoritmo3");
	aMostrar.push_back("9 - Ajuda");
	aMostrar.push_back("0 - Sair");
	iTex.menuNaConsola(aMostrar);

	escolha = iTex.smsRetorno("Escolha a opção pretendida:");

	if (escolha == "0")
	{
		iniciar();
	}
	else if (escolha == "1")
		algoritmo1();
	else if (escolha == "2")
		algoritmo2();
	else if (escolha == "3")
	    algoritmo3();
	else
		gestaoRotas();
}


//! Opção 1 do menuCliente: Introdução de um novo Cliente.

/*! Chama a interface criarCliente passando os par�metros por refer�ncia e
 *  processa o retorno da fun��o para criar um Cliente.
 */
void Empresa::registarCliente() {
	//! Par�metros a passar para a interface, são necessários para criar o Cliente.
	string nome, morada, teclado;
	int geoCoordID;
	string identificador; //! Identificador nó
	string latitude; //! Latitude
	string longitude; //! Longitude
	string projX; //! Projecção plana da longitude (X)
	string projY; //! Projecção plana da latitude (Y)
	vector<string> aMostrar;

	//! Recolha os dados dos cliente e faz a amostragem na tela.
	aMostrar.clear();
	aMostrar.push_back("Dados do Cliente");
	aMostrar.push_back("separador");
	nome = iTex.smsRetorno("Nome do Cliente:");
	aMostrar.push_back(nome);
	morada = iTex.smsRetorno("Morada do Cliente:");
	aMostrar.push_back(morada);
	identificador = iTex.smsRetorno("Identificador do cliente:");
	aMostrar.push_back(identificador);
	latitude = iTex.smsRetorno("Identificador geográfico do local:");
	aMostrar.push_back(latitude);


	iTex.menuNaConsola(aMostrar);
	teclado = iTex.smsRetorno("Confirme os dados(s/n)?");

	if (teclado == "s" || teclado == "S")
	{
		iData.novoCliente(nome, morada, identificador, latitude, longitude, projX, projY);

	}
	else
	{
		iTex.sms("Os dados serão descartados.");
	}
}


//! Função para alterar os dados do Cliente.
void Empresa::alterarCliente()
{
	/*string nomeCliente, confirma, escolha;
	int encontrados, indice;
	vector<string> aMostrar;
	vector<Cliente>::iterator iterCliente;
	vector<vector<Cliente>::iterator> lista;
	cin.ignore(10, '\n');

	nomeCliente = iTex.smsRetorno("Qual o nome do Cliente que pretende alterar? ");

	if(Dados.pesquisarCliente(nomeCliente, lista))		//! Faz a pesquisa, se for encontrado os resultados est�o em lista.
	{
		encontrados = lista.size();				//! Se for encontrado mais do que um Cliente, é preciso que o utilizador escolha o que pretende.
		if(encontrados == 1) indice = 0;		//! Se for apenas 1, deve ser esse o pretendido.
		else									//! Se forem vários, é preciso escolher 1 deles.
		{
			for(int i = 0; i < encontrados; i++)
				aMostrar.push_back(intToString(i + 1) + " - " + lista[i]->getnomeCliente());
			textos.menuNaConsola(aMostrar, '|', '-');
			aMostrar.clear();
			confirma = textos.smsRetorno("Escolha o Cliente que pretende alterar (qualquer outro valor cancela a altera��o):");
			try{indice = stringParaInteiro(confirma) - 1;}
			catch (...){indice = -1;} //! Caso o utilizador insira algo n�o transform�vel em inteiro, �ndice = -1.
			if(indice >= encontrados or indice < 0) indice = -1;//! O utilizador desistiu da altera��o, ou introduziu um valor inv�lido.
		}	//! A partir deste ponto indice � -1 ou um valor correspondente a um �ndice v�lido do vector lista.

		//! Apresentar informa��o do Cliente escolhido.
		if(indice != -1)	//! Mas apenas se n�o desistiu na escolha do Cliente de entre v�rios.
		{
			aMostrar.push_back("Cliente seleccionado para altera��o");
			aMostrar.push_back("separador");
			lista[indice]->imprime(aMostrar);
			iTex.menuNaConsola(aMostrar, '|', '-');
			aMostrar.clear();
			// **************************************
			//! O menu propriamente dito come�a agora.

			aMostrar.push_back("Alterar Cliente");
			aMostrar.push_back("separador");
			aMostrar.push_back("1 - Alterar Nome");
			aMostrar.push_back("2 - Alterar Morada");
			aMostrar.push_back("3 - Alterar Morada_gps");
			aMostrar.push_back("9 - Ajuda");
			aMostrar.push_back("0 - Sair");

			if(escolha == "0")
				gestaoCliente();

			if(escolha == "1")
				alterarNomeCliente();
			else if(escolha == "2")
				alterarMorada();
			else if(escolha == "3")
				alterarMorada_GPS();
			else if (escolha == "9")
				iTex.ajuda("menuPrincipal");

			else
			{
				aMostrar.push_back("Cliente n�o encontrado");
			    alterarCliente();
		    }
}*/
	}


void Empresa::desativarCliente()
{

}

void Empresa::consultarCliente()
{

}

void Empresa::capacidadeVeiculo()
{

}
void Empresa::clientesAlocados()
{

}
void Empresa::sucursalAssociado()
{

}

void Empresa::listaClientes()
{

}

void Empresa::veiculoAssociado()
{

}
void Empresa::desativarSucursal()
{

}

void Empresa::dadosCliente()
{

}

//! Futuro algoritmo para todas as rotas necessárias para um dia. Com redistribuição de 'serviço' por outro veículo com capacidade disponível, sendo o cliente atendido em sucursal diferente da que está registado.
void Empresa::algoritmo2()
{
	cout << "Algoritmo2" << endl;
}

//! Futuro algoritmo para todas as rotas necessárias para um dia. Com um veículo a realizar várias viagens para entregar todos os clientes na respectiva sucursal.
void Empresa::algoritmo3()
{
	cout << "Algoritmo3" << endl;
}

//! Algoritmo para a rota de apenas um veículo.


void Empresa::algoritmo1()
{
	int mapaX = 932;
	int mapaY = 619;
	float oeste = -8.63f;
	float este = -8.59f;
	float norte = 41.19f;
	float sul = 41.17f;
	char nos[] = "nodes.txt";
	char ruas[] = "roads.txt";
	char subruas[] = "subroads.txt";
	vector<int> rota;
	vector<int> visitar;
	//int idRota = 1;
	vector<no>::iterator pontoMapa;
	//! Relação entre as coordenadas geográficas e as utilizadas pelo GraphViewer.
	float dx = fabs(oeste-este)/mapaX;
	float dy = fabs(norte-sul)/mapaY;

	//! Construção do mapa da zona onde estão localizadas as rotas.
	mapa *miniMapa = new mapa(oeste, este, norte, sul, mapaX, mapaY);
	miniMapa->processaMapa(nos, ruas, subruas);

	//! Obtenção dos trajectos (rotas) a desenhar, utilizando os algoritmos adequados.
	//! Lista de sucursal e clientes a visitar.
	// TODO Ler as consultas de um dia e colocar os IDs das localizações no vector "visitar", até lá fica esta coisa manual.
	visitar.push_back(25504172);
	visitar.push_back(26015890);
	visitar.push_back(26016411);
	visitar.push_back(420807841);
	visitar.push_back(430284809);
	visitar.push_back(1223751653);

	//! Vsualização dos trajectos.
	GraphViewer *trajecto = new GraphViewer(mapaX, mapaY, false);
	trajecto->setBackground("map.jpeg");
	trajecto->createWindow(mapaX, mapaY);

	trajecto->defineEdgeColor("blue");
	trajecto->defineVertexColor("lightGray");

	//! Esta rotina executa o algoritmo para obter uma lista de IDs dos nós por forma a criar a interface gráfica.
	int lugares = 6;
	miniMapa->planearRotas(&rota, &visitar, lugares);

	//! Código a executar por cada rota.
	// TODO remover

	rota.push_back(25504172);
	rota.push_back(26015890);
	rota.push_back(26016411);
	rota.push_back(420807841);
	rota.push_back(430284809);
	rota.push_back(1223751653);

	unsigned int qtdeNos = rota.size();
	cout << qtdeNos << endl;

	for(unsigned int i = 0; i < qtdeNos; i++)
	{
		pontoMapa = miniMapa->infoNo(rota[i]);
		trajecto->addNode(pontoMapa->getID(), int(fabs(pontoMapa->latitude() - oeste) / dx), int(fabs(pontoMapa->longitude() - norte) / dy));
	}

	for(unsigned int i = 0; i < qtdeNos - 1; i++)
	{
		trajecto->addEdge(i, (miniMapa->infoNo(rota[i]))->getID(), (miniMapa->infoNo(rota[i+1]))->getID(),EdgeType::UNDIRECTED);
	}
	trajecto->addEdge(qtdeNos, (miniMapa->infoNo(rota[qtdeNos - 1]))->getID(), (miniMapa->infoNo(rota[0]))->getID(),EdgeType::UNDIRECTED);	// Ligar último ao primeiro.

	trajecto->rearrange();
	getchar();

	gestaoRotas();
}
